import React from "react";
import { Toast } from "antd-mobile";
// 导入组件
import { List, AutoSizer } from "react-virtualized";
import NavHeader from "../../components/NavHeader/NavHeader.js"
import * as styles from "./citylist.module.less";
// import styles from "./citylist.module.css"
// 引入封装的获取当前定位城市方法
import { getCurrentCity } from "../../utils/utils.js";
// 重构城市列表数据格式方法
const formatCityData = (list) => {
  // list：城市数据列表
  const cityList = {};
  // 1. 遍历list数组
  // 2. 获取每个城市信息中的名称简称的首字母进行分类
  // 3. 分类时要判断是否已经有该首字母分类了，已有的话直接push
  list.map((item) => {
    if (cityList[item.short.charAt(0)]) {
      cityList[item.short.charAt(0)].push(item);
    } else {
      cityList[item.short.charAt(0)] = [];
      cityList[item.short.charAt(0)].push(item);
    }
  });
  // Object.keys 返回传入的对象中的所有key组成的数组。
  const cityIndex = Object.keys(cityList).sort();
  return {
    cityList,
    cityIndex,
  };
};

// 处理cityIndex方法
const formatCityIndex = (cityIndex) => {
  switch (cityIndex) {
    case "#": return "当前定位" ;
    case "hot": return "热门城市";
    default :
      return cityIndex.toUpperCase();
  }
}

// 索引标题高度
const TITLE_HEIGHT = 36;
// 城市名称高度
const NAME_HEIGHT = 50 ;
// 有房源数据的城市列表
const HOUSE_CITY = ["北京","上海","广州","深圳"]
export default class CityList extends React.Component {
  constructor(){
    super();
    this.ListRef = React.createRef()
  }
  state = {
    cityList: {},
    cityIndex: [],
    // 高亮索引
    activeIndex:0
  };

  // 渲染List组件的每一行
  rowRenderer = ({
    key, // Unique key within array of rows 每一个列表项的标识key值
    index, // Index of row within collection 每一个列表项的索引号
    isScrolling, // The List is currently being scrolled 表示当前的列表项是否在滚动中
    isVisible, // This row is visible within the List (eg it is not an overscanned row) 当前列表项是否可见
    style, // Style object to be applied to row (to position it) 样式对象，指定每一行的位置
  }) => {
    // 会执行rowCount次
    const { cityIndex , cityList} = this.state;
    const letter = cityIndex[index];
    const cityListItem = cityList[letter];
    return (
      // 这里的返回值就是最终渲染出的每一行的内容
      <div key={key} style={style} className={styles.city}>
        <div className={styles.title}>{formatCityIndex(letter)}</div>
        {
          cityListItem.map((item)=> (
            <div key={item.value} className={styles.cityName} onClick={()=> this.changeCity(item)}>{item.label}</div>
          ))
        }
      </div>
    );
  }

  // 切换城市
  changeCity = ({label,value}) => {
     if (HOUSE_CITY.indexOf(label) > -1 ) { // 如果有房源数据
       localStorage.setItem("hkzf_city",JSON.stringify({label,value}));
       this.props.history.go(-1);
     }else{
       // 如果没有房源数据则弹出对话框提示用户
       // Toast组件轻提示  参数一为提示内容  参数二为展示秒数  参数三为关闭后的回调函数 参数四是 在展示时是否开启遮罩层防止操作提示框下的页面
       Toast.info("暂无该地区城市数据",1.5,null,false)
     }
  }
  // 索引列表点击跳转到对应行
  handleClick = (index) =>{
      this.ListRef.current.scrollToRow(index);
      console.log("点击索引",index);
  }

  // 渲染快速定位索引列表
  renderCityIndexList = () =>{
    return (
      <ul className={styles.cityIndexList}>
        {this.state.cityIndex.map((item , index) => (
                                                              // 避免在渲染时直接调用点击事件回调
          <li key={item} className={styles.cityIndexItem} onClick={()=> this.handleClick(index)}>
            <span className={this.state.activeIndex === index ?styles.cityIndexActive:""}>
              {item === "hot" ? "热" : item.toUpperCase()}
            </span>
          </li>
        ))}
      </ul>
    );
  }

  getCityList = async () => {
    const { data: res } = await React.$http.get("area/city", {
      params: {
        level: 1,
      },
    });
    if (res.status !== 200) return console.error("获取城市列表失败，请重试!");
    // 重构城市列表数据格式为所需要的数据格式
    const { cityList, cityIndex } = formatCityData(res.body);
    const { data: hotRes } = await React.$http.get("area/hot");
    if (hotRes.status !== 200)
      return console.error("获取热门城市信息失败，请重试!");
    cityList.hot = hotRes.body;
    cityIndex.splice(0, 0, "hot");
    const localCity = await getCurrentCity();
    cityList["#"] = [localCity];
    cityIndex.splice(0, 0, "#");
    this.setState(() => ({
      cityList,
      cityIndex,
    }));
  };

  // 动态设置每行的高度
  getRowHeight = ({index}) =>{
    // index是每行的索引号
    // 标题高度+城市数量*城市名称高度
    return TITLE_HEIGHT + this.state.cityList[this.state.cityIndex[index]].length * NAME_HEIGHT;
  }


  // 判断高亮索引
  onRowsRendered = ({startIndex}) => {
    //BUG: 该函数在第一次点击索引将对应行定位到顶部时会执行两次，而且第二次执行时startIndex还会减1
    console.log("定位索引:",startIndex);
    // 由于这个函数只要页面在滚动就会执行，为了避免不必要的频繁更新state，这里加上判断条件
    if ( startIndex !== this.state.activeIndex){
      this.setState(()=>({
        activeIndex : startIndex
      }))
    }
  }

 async componentDidMount() {
    // 获取城市列表
   await this.getCityList();
    // 调用measureAllRows提前计算所有行  调用方法时需要List绑定的变量中已经有数据，否则会报错。
    // 保证这个方法是在获取到数据之后执行，需要在上面的异步操作前加上await（同时需要在componentDidMount前面加上async）
    this.ListRef.current.measureAllRows();
  }

  render() {
    return (
      <div className={styles.citylist}>
        <NavHeader>
          城市列表
        </NavHeader>
        {
          // AutoSizer组件
          <AutoSizer>
            {({ height, width }) => (
              // 城市列表 List组件
              <List
                width={width}
                height={height}
                rowCount={this.state.cityIndex.length}
                rowHeight={this.getRowHeight}
                rowRenderer={this.rowRenderer}
                onRowsRendered={this.onRowsRendered}
                scrollToAlignment={"start"}
                ref={this.ListRef}
              />
            )}
          </AutoSizer>
        }
        {/*渲染快速定位索引列表*/}
        {this.renderCityIndexList()}
      </div>
    );
  }
}
